home *** CD-ROM | disk | FTP | other *** search
/ GameStar 2004 April / Gamestar_61_2004-04_dvdb.iso / DVDStar / Editace / hltp.exe / {app} / Source Code / MAP Viewer / MAPLoader.cpp < prev    next >
C/C++ Source or Header  |  2003-10-09  |  12KB  |  432 lines

  1. /*
  2. Half-Life MAP viewing utility.
  3. Copyright (C) 2003  Ryan Samuel Gregg
  4.  
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9.  
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18. */
  19.  
  20. #include "stdafx.h"
  21. #include "MAPLoader.h"
  22.  
  23. CMAPLoader::CMAPLoader(CConfig *Config, CRichTextBox *txtConsole)
  24. {
  25.     this->Config = Config;
  26.     this->txtConsole = txtConsole;
  27. }
  28.  
  29. bool CMAPLoader::LoadMAPFile(String *sFile, CWorld *World, CTextureManager *TextureManager)
  30. {
  31.     iLine = 0;
  32.     StreamReader *MAPFile;
  33.  
  34.     txtConsole->Print(String::Concat(S"Loading ", sFile, S"..."), Color::Green);
  35.  
  36.     try
  37.     {
  38.         MAPFile = File::OpenText(sFile);
  39.     }
  40.     catch(Exception *e)
  41.     {
  42.         txtConsole->Print(String::Concat(S"Error loading ", sFile, S": ", e->Message, S"\n"), Color::Red);
  43.         return false;
  44.     }
  45.  
  46.     try
  47.     {
  48.         String *sLine = NULL;
  49.         CEntity *Entity;
  50.  
  51.         while((sLine = MAPFile->ReadLine()) != NULL)
  52.         {
  53.             switch(ProcessLine(&sLine))
  54.             {
  55.                 case LineTypeEmpty:
  56.                     continue;
  57.                 case LineTypeOpenBrace:
  58.                     Entity = new CEntity(Config);
  59.                     if(ReadEntity(MAPFile, Entity, TextureManager))
  60.                     {
  61.                         World->AddEntity(Entity);
  62.                     }
  63.                     else
  64.                     {
  65.                         txtConsole->Print(String::Concat(S"Error loading ", sFile, S" on line ", iLine.ToString(), S".", S"\n"), Color::Red);
  66.                         MAPFile->Close();
  67.                         return false;
  68.                     }
  69.                     break;
  70.                 default:
  71.                     txtConsole->Print(String::Concat(S"Error loading ", sFile, S" on line ", iLine.ToString(), S".", S"\n"), Color::Red);
  72.                     MAPFile->Close();
  73.                     return false;
  74.             };
  75.         }
  76.     }
  77.     catch(Exception *e)
  78.     {
  79.         txtConsole->Print(String::Concat(S"Error loading ", sFile, S": ", e->Message, S"\n"), Color::Red);
  80.     }
  81.  
  82.     MAPFile->Close();
  83.  
  84.     return World->GetEntities()->Count != 0;
  85. }
  86.  
  87. bool CMAPLoader::ReadEntity(StreamReader *MAPFile, CEntity *Entity, CTextureManager *TextureManager)
  88. {
  89.     String *sLine = NULL;
  90.     CBrush *Brush;
  91.     while((sLine = MAPFile->ReadLine()) != NULL)
  92.     {
  93.         switch(ProcessLine(&sLine))
  94.         {
  95.             case LineTypeEmpty:
  96.                 continue;
  97.             case LineTypeArgVal:
  98.                 if(!sLine->StartsWith("\"") || ! sLine->EndsWith("\""))
  99.                     return false;
  100.  
  101.                 sLine = sLine->Remove(0, 1);
  102.                 sLine = sLine->Remove(sLine->Length - 1, 1);
  103.  
  104.                 int iPos;
  105.                 String *sArg, *sVal;
  106.  
  107.                 iPos = sLine->IndexOf("\" \"");
  108.                 if(iPos == -1)
  109.                     return false;
  110.  
  111.                 sArg = sLine->Substring(0, iPos);
  112.                 sVal = sLine->Substring(iPos + 3);
  113.                 Entity->AddArgVal(new CArgVal(sArg, sVal));
  114.                 break;
  115.             case LineTypeOpenBrace:
  116.                 Brush = new CBrush(Config);
  117.                 if(ReadBrush(MAPFile, Brush, TextureManager))
  118.                 {
  119.                     Entity->AddBrush(Brush);
  120.                 }
  121.                 else
  122.                 {
  123.                     return false;
  124.                 }
  125.                 break;
  126.             case LineTypeCloseBrace:
  127.                 return true;
  128.             default:
  129.                 return false;
  130.         };
  131.     }
  132.  
  133.     return false;
  134. }
  135.  
  136. bool CMAPLoader::ReadBrush(StreamReader *MAPFile, CBrush *Brush, CTextureManager *TextureManager)
  137. {
  138.     CMAPFaceManager *MAPFaceManager = new CMAPFaceManager();
  139.     String *sLine = NULL;
  140.     String *sTokens[];
  141.  
  142.     Vector *Normal, *UAxis, *VAxis, *V1, *V2, *V3;
  143.     Vertex2f Shift, Scale;
  144.     float Rotation;
  145.  
  146.     while((sLine = MAPFile->ReadLine()) != NULL)
  147.     {
  148.         switch(ProcessLine(&sLine))
  149.         {
  150.             case LineTypeEmpty:
  151.                 continue;
  152.             case LineTypeFace:
  153.                 sLine = sLine->Replace(S"  ", S" ");
  154.                 sTokens = sLine->Split(S" "->ToCharArray());
  155.  
  156.                 if(sTokens->Count == 31)
  157.                 {
  158.                     if(!sTokens[0]->Equals("("))
  159.                         return false;
  160.                     if(!sTokens[4]->Equals(")"))
  161.                         return false;
  162.                     if(!sTokens[5]->Equals("("))
  163.                         return false;
  164.                     if(!sTokens[9]->Equals(")"))
  165.                         return false;
  166.                     if(!sTokens[10]->Equals("("))
  167.                         return false;
  168.                     if(!sTokens[14]->Equals(")"))
  169.                         return false;
  170.  
  171.                     if(!sTokens[16]->Equals("["))
  172.                         return false;
  173.                     if(!sTokens[21]->Equals("]"))
  174.                         return false;
  175.                     if(!sTokens[22]->Equals("["))
  176.                         return false;
  177.                     if(!sTokens[27]->Equals("]"))
  178.                         return false;
  179.  
  180.                     try
  181.                     {
  182.                         V1 = new Vector(Convert::ToSingle(sTokens[ 1]), Convert::ToSingle(sTokens[ 2]), Convert::ToSingle(sTokens[ 3]));
  183.                         V2 = new Vector(Convert::ToSingle(sTokens[ 6]), Convert::ToSingle(sTokens[ 7]), Convert::ToSingle(sTokens[ 8]));
  184.                         V3 = new Vector(Convert::ToSingle(sTokens[11]), Convert::ToSingle(sTokens[12]), Convert::ToSingle(sTokens[13]));
  185.                         UAxis = new Vector(Convert::ToSingle(sTokens[17]), Convert::ToSingle(sTokens[18]), Convert::ToSingle(sTokens[19]));
  186.                         VAxis = new Vector(Convert::ToSingle(sTokens[23]), Convert::ToSingle(sTokens[24]), Convert::ToSingle(sTokens[25]));
  187.  
  188.                         Shift.X = Convert::ToSingle(sTokens[20]);
  189.                         Shift.Y = Convert::ToSingle(sTokens[26]);
  190.                         Scale.X = Convert::ToSingle(sTokens[29]);
  191.                         Scale.Y = Convert::ToSingle(sTokens[30]);
  192.  
  193.                         Rotation = Convert::ToSingle(sTokens[28]);
  194.  
  195.                         MAPFaceManager->AddMAPFace(new CMAPFace(V1, V2, V3, sTokens[15]->ToLower(), UAxis, VAxis, Shift, Scale, Rotation));
  196.                     }
  197.                     catch(Exception *e)
  198.                     {
  199.                         return false;
  200.                     }
  201.                 }
  202.                 else if(sTokens->Count >= 21)
  203.                 {
  204.                     if(!sTokens[0]->Equals("("))
  205.                         return false;
  206.                     if(!sTokens[4]->Equals(")"))
  207.                         return false;
  208.                     if(!sTokens[5]->Equals("("))
  209.                         return false;
  210.                     if(!sTokens[9]->Equals(")"))
  211.                         return false;
  212.                     if(!sTokens[10]->Equals("("))
  213.                         return false;
  214.                     if(!sTokens[14]->Equals(")"))
  215.                         return false;
  216.  
  217.                     try
  218.                     {
  219.                         V1 = new Vector(Convert::ToSingle(sTokens[ 1]), Convert::ToSingle(sTokens[ 2]), Convert::ToSingle(sTokens[ 3]));
  220.                         V2 = new Vector(Convert::ToSingle(sTokens[ 6]), Convert::ToSingle(sTokens[ 7]), Convert::ToSingle(sTokens[ 8]));
  221.                         V3 = new Vector(Convert::ToSingle(sTokens[11]), Convert::ToSingle(sTokens[12]), Convert::ToSingle(sTokens[13]));
  222.  
  223.                         Normal = VectorMath::CalculateNormal(V1, V2, V3);
  224.  
  225.                         // To do: Axis needs to be rotated by 'Rotation'.
  226.                         VectorMath::BestAxis(Normal, &UAxis, &VAxis);
  227.  
  228.                         Shift.X = Convert::ToSingle(sTokens[17]);
  229.                         Shift.Y = Convert::ToSingle(sTokens[18]);
  230.                         Scale.X = Convert::ToSingle(sTokens[19]);
  231.                         Scale.Y = Convert::ToSingle(sTokens[20]);
  232.  
  233.                         Rotation = Convert::ToSingle(sTokens[16]);
  234.  
  235.                         MAPFaceManager->AddMAPFace(new CMAPFace(V1, V2, V3, sTokens[15]->ToLower(), UAxis, VAxis, Shift, Scale, Rotation));
  236.                     }
  237.                     catch(Exception *e)
  238.                     {
  239.                         return false;
  240.                     }
  241.                 }
  242.                 else
  243.                 {
  244.                     return false;
  245.                 }
  246.                 break;
  247.             case LineTypeCloseBrace:
  248.                 BuildBrushFaces(MAPFaceManager, Brush, TextureManager);
  249.                 return true;
  250.                 break;
  251.             default:
  252.                 return false;
  253.         };
  254.     }
  255.  
  256.     return false;
  257. }
  258.  
  259. void CMAPLoader::BuildBrushFaces(CMAPFaceManager *MAPFaceManager, CBrush *Brush, CTextureManager *TextureManager)
  260. {
  261.     CMAPFace *MAPFace;
  262.     Vector *Normal;
  263.     ArrayList *Planes = new ArrayList();
  264.     for(int i = 0; i < MAPFaceManager->GetMAPFaces()->Count; i++)
  265.     {
  266.         MAPFace = static_cast<CMAPFace*>(MAPFaceManager->GetMAPFaces()->get_Item(i));
  267.         Normal = VectorMath::CalculateNormal(MAPFace->V1, MAPFace->V2, MAPFace->V3);
  268.         Planes->Add(new CPlane(Normal, Normal->Dot(MAPFace->V1)));
  269.     }
  270.  
  271.     ArrayList *Faces = new ArrayList();
  272.     for(int i = 0; i < Planes->Count; i++)
  273.     {
  274.         Faces->Add(new ArrayList());
  275.     }
  276.  
  277.     for(int i = 0; i < Planes->Count - 2; i++)
  278.     {
  279.         for(int j = 0; j < Planes->Count - 1; j++)
  280.         {
  281.             for(int k = 0; k < Planes->Count; k++)
  282.             {
  283.                 if(i != j && i != k && j != k)
  284.                 {
  285.                     Vector *vIntersection = new Vector();
  286.                     if(CPlane::GetIntersection(static_cast<CPlane*>(Planes->get_Item(i)), static_cast<CPlane*>(Planes->get_Item(j)), static_cast<CPlane*>(Planes->get_Item(k)), vIntersection) && VectorMath::PointInWorld(vIntersection))
  287.                     {
  288.                         CPlane *Plane;
  289.                         bool bLegal = true;
  290.  
  291.                         for(int l = 0; l < Planes->Count; l++)
  292.                         {
  293.                             if(l != i && l != j && l != k)
  294.                             {
  295.                                 Plane = static_cast<CPlane*>(Planes->get_Item(l));
  296.                                 if((Plane->Normal->Dot(vIntersection) - Plane->Distance) < EPSILON)
  297.                                 {
  298.                                     bLegal = false;
  299.                                     break;
  300.                                 }
  301.                             }
  302.                         }
  303.  
  304.                         if(bLegal)
  305.                         {
  306.                             if(!VectorMath::PointInVectors(static_cast<ArrayList*>(Faces->get_Item(i)), vIntersection))
  307.                                 static_cast<ArrayList*>(Faces->get_Item(i))->Add(vIntersection);
  308.  
  309.                             if(!VectorMath::PointInVectors(static_cast<ArrayList*>(Faces->get_Item(j)), vIntersection))
  310.                                 static_cast<ArrayList*>(Faces->get_Item(j))->Add(vIntersection);
  311.  
  312.                             if(!VectorMath::PointInVectors(static_cast<ArrayList*>(Faces->get_Item(k)), vIntersection))
  313.                                 static_cast<ArrayList*>(Faces->get_Item(k))->Add(vIntersection);
  314.                         }
  315.                     }
  316.                 }
  317.             }
  318.         }
  319.     }
  320.  
  321.     float fCount = 0.0f;
  322.     ArrayList *Face;
  323.     Vector *NewVector;
  324.  
  325.     Vector *Origin= new Vector();
  326.     for(int i = 0; i < Planes->Count; i++)
  327.     {
  328.         Face = static_cast<ArrayList*>(Faces->get_Item(i));
  329.         for(int j = 0; j < Face->Count; j++)
  330.         {
  331.             fCount++;
  332.             NewVector = static_cast<Vector*>(Face->get_Item(j));
  333.  
  334.             Origin->X += NewVector->X;
  335.             Origin->Y += NewVector->Y;
  336.             Origin->Z += NewVector->Z;
  337.         }
  338.     }
  339.  
  340.     fCount = 1.0f / fCount;
  341.     Origin->X *= fCount;
  342.     Origin->Y *= fCount;
  343.     Origin->Z *= fCount;
  344.  
  345.     CFace *BrushFace;
  346.     Vertex3f NewVertex;
  347.     for(int i = 0; i < Planes->Count; i++)
  348.     {
  349.         Face = static_cast<ArrayList*>(Faces->get_Item(i));
  350.         MAPFace = static_cast<CMAPFace*>(MAPFaceManager->GetMAPFaces()->get_Item(i));
  351.  
  352.         VectorMath::SortVectors(Face, VectorMath::CalculateNormal(MAPFace->V1, MAPFace->V2, MAPFace->V3));
  353.         VectorMath::ArrangeCCW(Origin, Face);
  354.  
  355.         BrushFace = new CFace(Config, Face->Count);
  356.  
  357.         NewVector = VectorMath::CalculateNormal(MAPFace->V1, MAPFace->V2, MAPFace->V3);
  358.         NewVertex.X = NewVector->X;
  359.         NewVertex.Y = NewVector->Y;
  360.         NewVertex.Z = NewVector->Z;
  361.  
  362.         BrushFace->SetNormal(NewVertex);
  363.  
  364.         for(int j = 0; j < Face->Count; j++)
  365.         {
  366.             NewVector = static_cast<Vector*>(Face->get_Item(j));
  367.             NewVertex.X = NewVector->X;
  368.             NewVertex.Y = NewVector->Y;
  369.             NewVertex.Z = NewVector->Z;
  370.  
  371.             BrushFace->SetVertex(j, NewVertex);
  372.         }
  373.         
  374.         for(int i = 0; i < SpecialTextures->Count; i++)
  375.         {
  376.             if(MAPFace->Texture->Equals(SpecialTextures[i]))
  377.             {
  378.                 BrushFace->SetSpecialTexture(true);
  379.                 break;
  380.             }
  381.         }
  382.  
  383.         Vertex2f Shift, Scale;
  384.         float Rotation;
  385.         Shift.X = MAPFace->Shift.X;
  386.         Shift.Y = MAPFace->Shift.Y;
  387.         Scale.X = MAPFace->Scale.X;
  388.         Scale.Y = MAPFace->Scale.Y;
  389.         Rotation = MAPFace->Rotation;
  390.         BrushFace->SetTextureInfo(TextureManager->AddTexture(MAPFace->Texture), MAPFace->AxisU, MAPFace->AxisV, Shift, Scale, Rotation);
  391.  
  392.         Brush->AddFace(BrushFace);
  393.     }
  394. }
  395.  
  396. int CMAPLoader::ProcessLine(String **sLine)
  397. {
  398.     iLine++;
  399.  
  400.     int iPos;
  401.  
  402.     iPos = (*sLine)->IndexOf("//");
  403.     if(iPos != -1)
  404.         *sLine = (*sLine)->Remove(iPos, (*sLine)->Length - iPos);
  405.  
  406.     iPos = (*sLine)->IndexOf(";");
  407.     if(iPos != -1)
  408.         *sLine = (*sLine)->Remove(iPos, (*sLine)->Length - iPos);
  409.  
  410.     *sLine = (*sLine)->Trim();
  411.  
  412.     if((*sLine)->Length == 0)
  413.     {
  414.         return LineTypeEmpty;
  415.     }
  416.     else if((*sLine)->Equals("{"))
  417.     {
  418.         return LineTypeOpenBrace;
  419.     }
  420.     else if((*sLine)->Equals("}"))
  421.     {
  422.         return LineTypeCloseBrace;
  423.     }
  424.     else if((*sLine)->StartsWith("("))
  425.     {
  426.         return LineTypeFace;
  427.     }
  428.     else
  429.     {
  430.         return LineTypeArgVal;
  431.     }
  432. }